﻿using System;
using System.Net;
using System.Xml;
using System.Xml.Serialization;

namespace Whois.API
{
    /// <summary>
    /// Provides a base for the service
    /// </summary>
    public abstract class ServiceBase<T> where T : class
    {
        /// <summary>
        /// Gets or Sets the username
        /// </summary>
        public string Username { get; set; }

        /// <summary>
        /// Gets or Sets the password
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// Gets or Sets the format of the url
        /// </summary>
        public string UrlFormat { get; set; }

        protected XmlSerializer Serializer { get; private set; }

        /// <summary>
        /// Creates new instance of the <c>ServiceBase</c>
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="urlFormat"></param>
        protected ServiceBase(string username, string password, string urlFormat)
        {
            Username = username;
            Password = password;
            UrlFormat = urlFormat;

            Serializer = new XmlSerializer(typeof(T));
        }

        /// <summary>
        /// Gets the response from the API based on the url format and the domain
        /// </summary>
        /// <returns></returns>
        public virtual T GetResponse(string domain)
        {
            //use the full url or build up partial
            string url = string.Format(UrlFormat, domain, Username, Password);

            //create the request
            HttpWebRequest request = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
            }
            catch (UriFormatException ex)
            {
                throw new WhoisApiException("WhoisApi Url error: " + url, ex);
            }
            request.Method = "GET";
            request.ContentType = "application/xml";

            //get the response and set the status & location
            var response = (HttpWebResponse)request.GetResponse();
            var returnVal = DeSerialize(response);
            response.Close();
            return returnVal;
        }

        protected virtual T DeSerialize(WebResponse response)
        {
            T result = default(T);
            using (var sr = response.GetResponseStream())
            {
                XmlDocument xml = new XmlDocument();
                xml.Load(sr);
                try
                {
                    using (var reader = new XmlNodeReader(xml))
                    {
                        result = (T) Serializer.Deserialize(reader);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    throw new WhoisApiException(xml, ex);
                }
            }
            return result;
        }
    }
}
